//
// Created by QU on 24-6-23.
//
#include <iostream>
#include <functional>
#include <utility>
#include <memory>
#include <vector>
#include <map>
#include <set>
#include <new>
#include <thread>
#include <algorithm>
#include <array>
#include <string>
#include <deque>

using std::cout, std::cin, std::endl;

int main(int argc, const char* argv[])
{
    cout << typeid(decltype(7 <=> 11)).name() << endl;

    struct B
    {
        int a;
        long b;
        auto operator <=>(const B&) const = default;
    };
    struct D : B
    {
        short c;
        auto operator <=>(const D&) const = default;
    };

    D x1{}, x2{};
    std::cout << typeid(decltype(x1 <=> x2)).name() << std::endl;
    // std::weak_ordering
    // 　  更多的用于自定义的类型比较

    /**
    现在C++20标准已经推荐使用<=>和==运算符自动生成其他比较运算符函数，而使用<、==以及std::rel_ops生成其他比较运算符函
    数则会因为std::rel_ops已经不被推荐使用而被编译器警告。那么对于老代码，我们是否需要去实现一套<=>和==运算符函数呢？其实
    大可不必，C++委员会在裁决这项修改的时候已经考虑到老代码的维护成本，所以做了兼容性处理，即在用户自定义类型中，实现了<、==运
    算符函数的数据成员类型，在该类型的三向比较中将自动生成合适的比较代码。
    */

    struct Legacy {
        int n;
        bool operator==(const Legacy& rhs) const
        {
            return n == rhs.n;
        }
        bool operator<(const Legacy& rhs) const
        {
            return n < rhs.n;
        }
    };

    struct TreeWay {
        Legacy m;
        std::strong_ordering operator<=>(const TreeWay &) const =
      default;
    };

    TreeWay t1, t2;
    bool r = t1 < t2;

    /**
    本章介绍了C++20新增的三向比较特性，该特性的引入为实现比较运算提供了方便。我们只需要实现==和<=>两个运算符函数，剩下的4
    个运算符函数就可以交给编译器自动生成了。虽说std::rel_ops在实现了==和<两个运算符函数以后也能自动提供剩下的4个运算符函
    数，但显然用三向比较更加便捷。另外，三向比较提供的3种结果类型也是std::rel_ops无法媲美的。进一步来说，由于三向比较的出
    现，std::rel_ops在C++20中已经不被推荐使用了。最后，C++委员会没有忘记兼容性问题，这让三向比较能够通过运算符函数<和==来
    自动生成。
    */


    // std::partial_ordering
    std::cout << typeid(decltype(7.7 <=> 11.1)).name();
    // 用MSVC编译运行以上代码会输出classQstd::partial_ordering。之所以会输出class
    // std::partial_ordering而不是std::strong_ordering，是因为浮点的集合中存在一个特殊的NaN，它和其他浮点数值是没关系的

    // 后面的内容来自 ChatGPT
    //////////
    // C++20引入的三路比较运算符（<=>），也称为“太空飞船运算符”，是用于简化和统一比较操作的新特性。
    // 它的引入使得编写更少的代码即可实现全套的比较运算（<, <=, >, >=, ==, !=）。以下是对C++20中的<=>运算符的详细介绍：

    // 基本概念
    // 三路比较运算符<=>是一种组合比较运算符，它返回一个表示比较结果的值，该值可以是以下三种状态之一：

    // 小于 // 等于 // 大于
    // 这个运算符适用于整型、浮点型、字符串、容器等多种类型，并且能够自动生成传统的比较运算符。

    // 返回类型
    // <=>运算符的返回类型依赖于被比较的类型：

    // std::strong_ordering：表示强序关系。适用于大多数内建类型，如整型、浮点型。
    // std::weak_ordering：表示弱序关系。适用于部分自定义类型。
    // std::partial_ordering：表示部分序关系。适用于一些不完全排序的类型，如NaN的浮点数比较。

    // 示例代码
    int a = 5, b = 10;

    auto result = a <=> b;

    if (result < 0)
    {
        std::cout << "a is less than b\n";
    }
    else if (result > 0)
    {
        std::cout << "a is greater than b\n";
    }
    else
    {
        std::cout << "a is equal to b\n";
    }

    // 自定义类型的比较
    // 对于自定义类型，可以通过重载 // <= // > 运算符来实现比较操作：

    struct Point1
    {
        int x, y;

        auto operator<=>(const Point1&) const = default; // 自动生成<=>运算符
    };

    {
        Point1 p1{1, 2};
        Point1 p2{2, 3};

        auto result = p1 <=> p2;

        if (result < 0)
        {
            std::cout << "p1 is less than p2\n";
        }
        else if (result > 0)
        {
            std::cout << "p1 is greater than p2\n";
        }
        else
        {
            std::cout << "p1 is equal to p2\n";
        }
    }

    // 自动生成的比较运算符
    // 如果为类型定义了 // <= // > // 运算符，编译器会自动生成相应的比较运算符（如<,  <=, > , >= , == , != ）。 例如：

    struct Point2
    {
        int x, y;

        auto operator<=>(const Point2&) const = default;
    };

    {
        Point2 p1{1, 2};
        Point2 p2{2, 3};

        std::cout << std::boolalpha;
        std::cout << (p1 == p2) << std::endl; // 输出: false
        std::cout << (p1 != p2) << std::endl; // 输出: true
        std::cout << (p1 < p2) << std::endl; // 输出: true
        std::cout << (p1 <= p2) << std::endl; // 输出: true
        std::cout << (p1 > p2) << std::endl; // 输出: false
        std::cout << (p1 >= p2) << std::endl; // 输出: false
    }
    return 0;
}

// 使用 <= > 简化代码 在实际应用中， <= > 运算符可以极大简化比较操作的实现，使代码更加简洁和易于维护。
// 例如，在实现自定义容器或排序算法时，可以使用 <= > 来自动生成全套的比较逻辑。

// C++20引入的 <= > 运算符提供了一种统一的方式来进行比较操作，简化了代码编写，并且自动生成全套的比较运算符。
// 它支持多种类型，包括内建类型和自定义类型，对于提升代码的简洁性和可维护性非常有用。
// 在实际开发中，充分利用 <= > 运算符可以显著减少样板代码，提高开发效率。
